package redis

import (
	"context"
	"time"

	"github.com/beego/beego/v2/core/config"
	"github.com/beego/beego/v2/core/logs"
	"github.com/go-redis/redis/v8"
)

type Redis interface {
	Connect() *redis.Client
	Close()
	Get(key string) string
	Set(key string, value string, expire int) bool
	HExists(key string, field string) bool
	HSet(key string, values ...interface{}) int64
	HGet(key string, field string) string
}

type Z *redis.Z

type MyRedis struct {
}

var ctx = context.Background()
var client *redis.Client

func init() {
	var r MyRedis
	client = r.Connect()
	//defer func(rdb MyRedis) {
	//	rdb.Close()
	//}(r)
}

func (r *MyRedis) Connect() *redis.Client {
	rHost, _ := config.String("redis::rHost")
	rPort, _ := config.String("redis::rPort")
	rPass, _ := config.String("redis::rPass")
	// logs.Info(rPass)
	return redis.NewClient(&redis.Options{
		Addr:     rHost + ":" + rPort,
		Password: rPass, // no password set
		DB:       0,     // use default DB
	})
}

func (r *MyRedis) Close() {
	err := client.Close()
	if err != nil {
		logs.Error(err.Error())
	}
}

// Set
// 存储 key-value 到Redis
func (r *MyRedis) Set(key string, value string, expire int) bool {
	//连接Redis
	err := client.Set(ctx, key, value, time.Duration(expire)*time.Second).Err()
	if err != nil {
		logs.Warn(err.Error())
		return false
	} else {
		//logs.Info("Redis Save Data Success : key[", key, "]-value[", value, "]")
		return true
	}
}

// Get
// 读取Redis数据
func (r *MyRedis) Get(key string) string {
	value, err := client.Get(ctx, key).Result()
	if err != nil {
		//logs.Warn(err.Error())
		return ""
	} else {
		//logs.Info("Redis Read Data Success : key[", key, "]-value[", value, "]")
		return value
	}
}

func (r *MyRedis) HExists(key string, field string) bool {
	cmd := client.HExists(ctx, key, field)
	return cmd.Val()
}

func (r *MyRedis) HSet(key string, values ...interface{}) int64 {
	cmd := client.HSet(ctx, key, values)
	return cmd.Val()
}

func (r *MyRedis) HGet(key string, field string) string {
	cmd := client.HGet(ctx, key, field)
	return cmd.Val()
}

func (r *MyRedis) Exists(key ...string) bool {
	cmd := client.Exists(ctx, key...)
	if cmd.Val() == 1 {
		return true
	} else {
		return false
	}
}

func (r *MyRedis)Keys(pattern string)[]string{
	cmd := client.Keys(ctx,pattern)
	return cmd.Val()
}

func (r *MyRedis)Del(keys ...string)int64{
	cmd := client.Del(ctx,keys...)
	return cmd.Val()
}

func (r *MyRedis)ZAdd(key string,members ...*redis.Z)int64{
	cmd := client.ZAdd(ctx,key,members...)
	return cmd.Val()
}

func (r *MyRedis)ZIncrBy(key string,increment float64,member string)float64{
	cmd := client.ZIncrBy(ctx,key,increment,member)
	return cmd.Val()
}

func (r *MyRedis)ZRange(key string,start int64,stop int64)[]string{
	cmd := client.ZRange(ctx,key,start,stop)
	return cmd.Val()
}

func (r *MyRedis)ZRevRange(key string,start int64,stop int64)[]string{
	cmd := client.ZRevRange(ctx,key,start,stop)
	return cmd.Val()
}


func (r *MyRedis)Expire(key string,expire int)bool{
	cmd := client.Expire(ctx,key,time.Duration(expire) * time.Second)
	return cmd.Val()
}